package com.cq.androidtools.jetpack.databinding

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import java.util.*


/**
 * 作者: CQ
 * 日期: 2021-07-01
 * 说明:
 */
abstract class DataBindingAdapter<VB : ViewDataBinding, T> :
    RecyclerView.Adapter<DataBindingAdapter.BaseViewHolder>() {

    //定义的数据
    private var mData: List<T> = mutableListOf()


    /**
     * 引用MultiTypeViewHolder
     */
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
        return BaseViewHolder(
            getViewBinding(
                LayoutInflater.from(parent.context),
                parent
            )
        )
    }

    /**
     * 绑定数据
     */
    override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
        onBindItem(DataBindingUtil.getBinding(holder.itemView), getItem(position), position)
    }

    protected abstract fun onBindItem(binding: VB?, t: T, position: Int)
    /**
     * 刷新数据
     */
    fun setData(data: List<T>?) {
        data?.let {
            val result = DiffUtil.calculateDiff(object  : DiffUtil.Callback(){
                override fun getOldListSize(): Int {
                    return mData.size
                }

                override fun getNewListSize(): Int {
                    return it.size
                }

                override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                    val oldData: T = mData[oldItemPosition]
                    val newData: T = it[newItemPosition]
                    return this@DataBindingAdapter.areItemsTheSame(oldData, newData)
                }

                override fun areContentsTheSame(
                    oldItemPosition: Int,
                    newItemPosition: Int
                ): Boolean {
                    val oldData: T = mData[oldItemPosition]
                    val newData: T = it[newItemPosition]
                    return this@DataBindingAdapter.areItemContentsTheSame(oldData, newData, oldItemPosition, newItemPosition)
                }
            })
            mData = data
            result.dispatchUpdatesTo(this)
        }?: let {
            mData = mutableListOf()
            notifyItemRangeChanged(0, mData.size)
        }

    }
    fun addData(data: List<T>?, position: Int? = null) {
        if (!data.isNullOrEmpty()) {
            with(LinkedList(mData)) {
                position?.let {
                    val startPosition = when {
                        it < 0 -> 0
                        it >= size -> size
                        else -> it
                    }
                    addAll(startPosition, data)
                } ?: addAll(data)
                setData(this)
            }
        }
    }

    /**
     * 获取 T
     */
    fun getItem(position: Int): T {
        return mData[position]
    }


    /**
     * 创建一个公共的ViewHolder，避免重复创建
     */
    class BaseViewHolder(var binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root)

    /**
     * 获取数据的总数量
     */
    override fun getItemCount(): Int {
        return mData.size
    }



    open fun areItemContentsTheSame(oldItem: T, newItem: T, oldItemPosition: Int, newItemPosition: Int): Boolean {
        return oldItem == newItem
    }


    /**
     * 在BaseAdapter中实现了这2个方法，因为我们不知道子类在实现的时候是否需要改变对比的方式。比如我在使用areItemsTheSame的时候，
     * 泛型T如果泛型T不是一个基本数据类型，通常只需要对比泛型T中的唯一key就可以
     */
    open fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
        return oldItem == newItem
    }

}